home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / oscar / rendezvous / reactsocket.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  8KB  |  222 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. from common.timeoutsocket import TimeoutSocketOne
  5. from util.net import SocketEventMixin
  6. import common
  7. import socket
  8. from functools import partial
  9. from logging import getLogger
  10. from util import Timer
  11. log = getLogger('oscar.reactsocket')
  12. info = log.info
  13.  
  14. class OscarTimeoutSocket(common.socket):
  15.     
  16.     def tryconnect(self, ips, on_connect, on_fail, timeout = 2):
  17.         self._connectedonce = False
  18.         info('tryconnect Y=%r, N=%r', on_connect, on_fail)
  19.         self.ips = self.iptuples(ips)
  20.         if not callable(on_connect) or not callable(on_fail):
  21.             raise TypeError('on_connect and on_fail must be callables')
  22.         
  23.         self.on_connect = on_connect
  24.         self.on_fail = on_fail
  25.         self.timetowait = timeout
  26.         self._tryagain(timeout)
  27.  
  28.     
  29.     def tryaccept(self, addr, on_connect, on_fail, timeout = 1.5):
  30.         self._connectedonce = False
  31.         info('tryaccept Y=%r, N=%r', on_connect, on_fail)
  32.         self.ips = ()
  33.         self.on_connect = on_connect
  34.         self.on_fail = on_fail
  35.         info('listening for a connection at %s:%d', *addr)
  36.         self.bind(addr)
  37.         self.listen(1)
  38.         if timeout:
  39.             info('timeout in %r secs', timeout)
  40.             
  41.             def dotimeout():
  42.                 info('TIMEOUT. calling %r', self.on_fail)
  43.                 self.on_fail
  44.  
  45.             self.timeout = Timer(timeout, dotimeout)
  46.             self.timeout.start()
  47.         
  48.  
  49.     
  50.     def _tryagain(self, timetowait):
  51.         addr = self.ips.pop(0)
  52.         if len(self.ips) > 0:
  53.             timeoutfunc = partial(self._tryagain, timetowait)
  54.         else:
  55.             timeoutfunc = self.on_fail
  56.         self.timeout = Timer(timetowait, timeoutfunc)
  57.         info('%r attempting conn: %s:%d', self, *addr)
  58.         self.make_socket()
  59.         self.connect(addr, error = timeoutfunc)
  60.         info('timeout is %r seconds...', timetowait)
  61.         if self.timeout is not None:
  62.             self.timeout.start()
  63.         
  64.  
  65.     
  66.     def handle_expt(self):
  67.         info('handle_expt in %r', self)
  68.         self.handle_disconnect()
  69.  
  70.     
  71.     def handle_error(self, e = None):
  72.         info('handle_error in %r', self)
  73.         import traceback as traceback
  74.         traceback.print_exc()
  75.         if not self._connectedonce:
  76.             self.handle_disconnect()
  77.         else:
  78.             self.close()
  79.  
  80.     
  81.     def handle_disconnect(self):
  82.         self.cancel_timeout()
  83.         self.close()
  84.         if len(self.ips) > 0:
  85.             info('got an error, trying next ip immediately: ' + repr(self.ips[0]))
  86.             self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
  87.             self._tryagain(self.timetowait)
  88.         elif not self._connectedonce:
  89.             info('no more ips to attempt, calling on_fail (%r)', self.on_fail)
  90.             self.on_fail()
  91.         
  92.  
  93.     
  94.     def handle_connect(self):
  95.         info('connected!')
  96.         self.cancel_timeout()
  97.         self._connectedonce = True
  98.         self.on_connect()
  99.         self.on_fail = Sentinel
  100.  
  101.     
  102.     def handle_accept(self):
  103.         self.cancel_timeout()
  104.         (conn, address) = self.accept()
  105.         info('%r connection accepted (%r), canceling timeout and calling %r', self, address, self.on_connect)
  106.         self._connectedonce = True
  107.         self.on_connect(conn)
  108.  
  109.     
  110.     def cancel_timeout(self):
  111.         if hasattr(self, 'timeout') and self.timeout is not None:
  112.             self.timeout.cancel()
  113.             self.timeout = None
  114.         
  115.  
  116.     
  117.     def iptuples(self, ips):
  118.         if not hasattr(ips, '__len__'):
  119.             raise TypeError('ips must be (host, port) or [(host,port), (host,port)]')
  120.         
  121.         if not hasattr(ips[0], '__len__'):
  122.             ips = tuple([
  123.                 ips])
  124.         
  125.         return ips
  126.  
  127.     
  128.     def __repr__(self):
  129.         
  130.         try:
  131.             pn = self.getpeername()
  132.         except Exception:
  133.             pn = None
  134.  
  135.         return '<TimeoutSocket peername=%r ips=%r at 0x%08x>' % (pn, getattr(self, 'ips', None), id(self))
  136.  
  137.  
  138.  
  139. class ReactSocket(OscarTimeoutSocket):
  140.     
  141.     def __init__(self, connected_socket = None, on_close = (lambda : pass)):
  142.         if connected_socket is None:
  143.             OscarTimeoutSocket.__init__(self)
  144.         else:
  145.             OscarTimeoutSocket.__init__(self, connected_socket)
  146.         self._connectedonce = True
  147.         self.data = ''
  148.         self.original_collector = self.collect_incoming_data
  149.         self.collectors = []
  150.         self.on_close = on_close
  151.  
  152.     
  153.     def handle_close(self):
  154.         log.info('%r handle_close', self)
  155.         self.on_close()
  156.         self.close()
  157.  
  158.     
  159.     def collect_incoming_data(self, data):
  160.         self.data += data
  161.  
  162.     
  163.     def push_collector(self, collector):
  164.         self.collectors.append(collector)
  165.         self.collect_incoming_data = self.collectors[-1]
  166.  
  167.     
  168.     def pop_collector(self):
  169.         self.collectors.pop(-1)
  170.         self.collect_incoming_data = None if self.collectors else self.original_collector
  171.  
  172.     
  173.     def receive_next(self, size, callable_func):
  174.         if hasattr(size, '_struct'):
  175.             size = size._struct.size
  176.         
  177.         
  178.         self.found_terminator = lambda : callable_func(self.data)
  179.         self.data = ''
  180.         self.set_terminator(size)
  181.  
  182.  
  183.  
  184. class ReactSocketOne(TimeoutSocketOne, SocketEventMixin):
  185.     
  186.     def __init__(self, *a, **k):
  187.         common.TimeoutSocketOne.__init__(self, *a, **k)
  188.         SocketEventMixin.__init__(self)
  189.         self.data = ''
  190.         self.original_collector = self.collect_incoming_data
  191.         self.collectors = []
  192.  
  193.     
  194.     def collect_incoming_data(self, data):
  195.         self.data += data
  196.  
  197.     
  198.     def push_collector(self, collector):
  199.         self.collectors.append(collector)
  200.         self.collect_incoming_data = self.collectors[-1]
  201.  
  202.     
  203.     def pop_collector(self):
  204.         self.collectors.pop(-1)
  205.         self.collect_incoming_data = None if self.collectors else self.original_collector
  206.  
  207.     
  208.     def receive_next(self, size, callable_func):
  209.         if hasattr(size, '_struct'):
  210.             size = size._struct.size
  211.         
  212.         
  213.         self.found_terminator = lambda : callable_func(self.data)
  214.         self.data = ''
  215.         self.set_terminator(size)
  216.  
  217.     
  218.     def __getattr__(self, attr):
  219.         return getattr(self.socket, attr)
  220.  
  221.  
  222.